package sensorBoard.io;

import java.util.Vector;

import sensorBoard.ISensorBoardComponent;
import server.interfaces.ISensorBoardManager;

import com.CharNotValidException;
import com.Event;
import com.LedsManager;
import com.ParamNotFoundException;
import com.ParamsLabel;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.resources.transducers.ISwitch;
import com.sun.spot.resources.transducers.LEDColor;

/**
 * Provides the access to the node Switches. Provides information about the switches status (PRESSED OR RELEASED)
 * and builds instances of SwitchListener. 
 * @author Francesco Aiello, Antonio Guerrieri, Raffaele Gravina
 *
 */
public class SwitchInput implements ISensorBoardComponent {
	
	private byte [] handlableEvents = {Event.SWT_PRESSED_RELEASED, 
			Event.SWT_TERMINATION};
	private ISwitch [] iSwitches;
	private ISensorBoardManager ioManager;
	private Vector switchListeners;
	
	/**
	 * The constructor needs to know own ioManager and the ISwitches class provided by SunSPOT SDK 
	 * @param ioManager its own manager
	 */
	public SwitchInput (ISensorBoardManager ioManager) {
		this.ioManager = ioManager;
		this.iSwitches = EDemoBoard.getInstance().getSwitches();
		this.switchListeners = new Vector();
	}
	
	public boolean IsEventHandlable(byte eventName) {
		for (int i = 0; i < handlableEvents.length; i++) 
			if (this.handlableEvents[i] == eventName)
				return true;
		return false;
	}
	
	public void handleEvent(Event event) {
		
		
		byte eventName = event.getName();
		switch (eventName) {
			case Event.SWT_PRESSED_RELEASED:
				if (event.getType() == Event.NOW) {
					//is pressed and/or release NOW?
					try {
						int index = Integer.parseInt(event.getParam(ParamsLabel.LED_COLOR));
						if (index == 0 || index == 1) {
							if (this.iSwitches[index].isOpen()) {
								event.setParam(ParamsLabel.SWT_PRESSED, "false");
							}
							else if (this.iSwitches[index].isClosed()) {
								event.setParam(ParamsLabel.SWT_PRESSED, "true");
							}
							this.ioManager.send(event);
						}
					}
					catch (NumberFormatException e) {
						LedsManager.error(LEDColor.YELLOW);
						e.printStackTrace();
					}
					catch (ParamNotFoundException e) {
						LedsManager.error(LEDColor.YELLOW);
						e.printStackTrace();
					}
					catch (CharNotValidException e) {
						LedsManager.error(LEDColor.YELLOW);
						e.printStackTrace();
					}
				}
				else if (event.getType() != Event.NOW) {
					String ioID = this.ioManager.generateSensorBoardComponentID();
					this.switchListeners.addElement(new SwitchListener(this, ioID, event));
					Event ioIDEvent = new Event("", event.getTargetID(), Event.SWT_ID, Event.NOW);
					try {
						ioIDEvent.setParam(ParamsLabel.INO_ID, ioID);
						this.ioManager.send(ioIDEvent);
					}
					catch (CharNotValidException e) {
						LedsManager.error(LEDColor.YELLOW);
						e.printStackTrace();
					}
				}
			break;
			case Event.SWT_TERMINATION:
				try {
					String ioID = event.getParam(ParamsLabel.INO_ID);
					if (!ioID.equals("")) {
						if (this.terminateListener(ioID))
							this.ioManager.send(event);
					}
				}
				catch (ParamNotFoundException e) {
					LedsManager.error(LEDColor.YELLOW);
					e.printStackTrace();
				}
			break;
			
		}
		
	}
	
	public void send(Event backEvent) {
		this.ioManager.send(backEvent);
	}
	
	public boolean terminateListener(String ioID) {
		for (int i = 0; i < this.switchListeners.size(); i++) {
			SwitchListener switchListener = (SwitchListener)this.switchListeners.elementAt(i);
			if ( switchListener.getSensorBoardComponentID().equals(ioID) ) {
				this.switchListeners.removeElementAt(i);
				return switchListener.terminateListener(); 
			}
		}
		return false;
	}
	
}


